import * as THREE from 'three';
import { Vec3 } from '@/core/types';
import { Entity } from '@/entities/Entity';

// 聊天气泡数据接口
interface ChatBubble {
  id: string;
  entity: Entity;
  message: string;
  element: HTMLElement;
  startTime: number;
  duration: number;
  isVisible: boolean;
}

// 聊天气泡管理器
export class ChatBubbleManager {
  private bubbles: Map<string, ChatBubble> = new Map();
  private container!: HTMLElement;
  private camera?: THREE.Camera;
  private defaultDuration = 3000; // 3秒显示时间
  private maxDistance = 20; // 最大显示距离
  private minScale = 0.5; // 最小缩放比例
  private maxBubbleWidth = 250; // 最大气泡宽度

  constructor() {
    this.createContainer();
    this.addStyles();
  }

  private createContainer(): void {
    this.container = document.createElement('div');
    this.container.id = 'chat-bubbles-container';
    this.container.className = 'chat-bubbles-container';
    document.body.appendChild(this.container);
  }

  private addStyles(): void {
    const style = document.createElement('style');
    style.textContent = `
      .chat-bubbles-container {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        pointer-events: none;
        z-index: 100;
      }
      
      .chat-bubble {
        position: absolute;
        background: rgba(0, 0, 0, 0.85);
        color: white;
        padding: 10px 14px;
        border-radius: 16px;
        font-family: 'Microsoft YaHei', 'SimHei', sans-serif;
        font-size: 14px;
        max-width: ${this.maxBubbleWidth}px;
        word-wrap: break-word;
        word-break: break-word;
        text-align: left;
        border: 2px solid rgba(255, 255, 255, 0.3);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
        transform: translate(-50%, -100%);
        animation: chatBubbleAppear 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
        line-height: 1.4;
        white-space: pre-wrap;
        backdrop-filter: blur(4px);
      }
      
      .chat-bubble::after {
        content: '';
        position: absolute;
        top: 100%;
        left: 50%;
        transform: translateX(-50%);
        border: 10px solid transparent;
        border-top-color: rgba(0, 0, 0, 0.85);
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
      }
      
      .chat-bubble.fade-out {
        animation: chatBubbleFadeOut 0.6s ease-in forwards;
      }
      
      .chat-bubble.distant {
        opacity: 0.7;
        transform: translate(-50%, -100%) scale(0.8);
      }
      
      .chat-bubble.very-distant {
        opacity: 0.4;
        transform: translate(-50%, -100%) scale(0.6);
      }
      
      @keyframes chatBubbleAppear {
        0% {
          opacity: 0;
          transform: translate(-50%, -100%) scale(0.6) translateY(10px);
        }
        60% {
          transform: translate(-50%, -100%) scale(1.05) translateY(-2px);
        }
        100% {
          opacity: 1;
          transform: translate(-50%, -100%) scale(1) translateY(0);
        }
      }
      
      @keyframes chatBubbleFadeOut {
        0% {
          opacity: 1;
          transform: translate(-50%, -100%) scale(1);
        }
        100% {
          opacity: 0;
          transform: translate(-50%, -100%) scale(0.8) translateY(-10px);
        }
      }
      
      /* 长文本处理 */
      .chat-bubble.long-text {
        max-width: 300px;
        font-size: 13px;
        line-height: 1.3;
      }
      
      .chat-bubble.very-long-text {
        max-width: 350px;
        font-size: 12px;
        line-height: 1.2;
        max-height: 120px;
        overflow-y: auto;
      }
      
      /* 滚动条样式 */
      .chat-bubble.very-long-text::-webkit-scrollbar {
        width: 4px;
      }
      
      .chat-bubble.very-long-text::-webkit-scrollbar-track {
        background: rgba(255, 255, 255, 0.1);
        border-radius: 2px;
      }
      
      .chat-bubble.very-long-text::-webkit-scrollbar-thumb {
        background: rgba(255, 255, 255, 0.3);
        border-radius: 2px;
      }
    `;
    document.head.appendChild(style);
  }

  /**
   * 设置相机引用（用于世界坐标到屏幕坐标转换）
   */
  public setCamera(camera: THREE.Camera): void {
    this.camera = camera;
  }

  /**
   * 显示聊天气泡
   */
  public showBubble(entity: Entity, message: string, duration?: number): void {
    const bubbleId = entity.getId();
    
    // 如果该实体已有气泡，先移除
    if (this.bubbles.has(bubbleId)) {
      this.removeBubble(bubbleId);
    }

    // 创建气泡元素
    const element = this.createBubbleElement(message);

    // 创建气泡数据
    const bubble: ChatBubble = {
      id: bubbleId,
      entity,
      message,
      element,
      startTime: Date.now(),
      duration: duration || this.defaultDuration,
      isVisible: true
    };

    // 添加到容器和映射
    this.container.appendChild(element);
    this.bubbles.set(bubbleId, bubble);

    // 更新位置
    this.updateBubblePosition(bubble);

    // 设置自动移除
    setTimeout(() => {
      this.removeBubble(bubbleId);
    }, bubble.duration);

    console.log(`显示聊天气泡: ${entity.getType()} - ${message}`);
  }

  /**
   * 创建气泡DOM元素
   */
  private createBubbleElement(message: string): HTMLElement {
    const element = document.createElement('div');
    element.className = 'chat-bubble';
    
    // 处理长文本
    const textLength = message.length;
    if (textLength > 100) {
      element.classList.add('very-long-text');
    } else if (textLength > 50) {
      element.classList.add('long-text');
    }
    
    // 处理文本换行
    const processedMessage = this.processMessageText(message);
    element.textContent = processedMessage;

    return element;
  }

  /**
   * 处理消息文本，添加适当的换行
   */
  private processMessageText(message: string): string {
    // 如果消息很长，在适当位置添加换行
    if (message.length <= 30) {
      return message;
    }

    // 按句子分割
    const sentences = message.split(/([。！？.!?])/);
    let result = '';
    let currentLine = '';

    for (let i = 0; i < sentences.length; i += 2) {
      const sentence = sentences[i] + (sentences[i + 1] || '');
      
      if (currentLine.length + sentence.length > 25) {
        if (currentLine) {
          result += currentLine + '\n';
          currentLine = sentence;
        } else {
          result += sentence + '\n';
        }
      } else {
        currentLine += sentence;
      }
    }
    
    if (currentLine) {
      result += currentLine;
    }

    return result.trim();
  }

  /**
   * 移除聊天气泡
   */
  public removeBubble(bubbleId: string): void {
    const bubble = this.bubbles.get(bubbleId);
    if (!bubble) return;

    // 添加淡出动画
    bubble.element.classList.add('fade-out');
    bubble.isVisible = false;
    
    // 动画结束后移除元素
    setTimeout(() => {
      if (bubble.element.parentNode) {
        bubble.element.parentNode.removeChild(bubble.element);
      }
      this.bubbles.delete(bubbleId);
    }, 600);
  }

  /**
   * 更新所有气泡位置和状态
   */
  public update(playerPosition?: Vec3): void {
    for (const bubble of this.bubbles.values()) {
      if (!bubble.isVisible) continue;

      this.updateBubblePosition(bubble, playerPosition);
      
      // 检查是否超时
      const elapsed = Date.now() - bubble.startTime;
      if (elapsed >= bubble.duration) {
        this.removeBubble(bubble.id);
      }
    }
  }

  /**
   * 更新单个气泡位置
   */
  private updateBubblePosition(bubble: ChatBubble, playerPosition?: Vec3): void {
    if (!this.camera) {
      // 如果没有相机，使用简单的固定位置
      bubble.element.style.left = '50%';
      bubble.element.style.top = '20%';
      return;
    }

    try {
      // 获取实体位置
      const entityPos = bubble.entity.getPosition();
      
      // 计算距离感知缩放
      if (playerPosition) {
        this.applyDistanceScaling(bubble, entityPos, playerPosition);
      }
      
      // 将世界坐标转换为屏幕坐标
      const screenPos = this.worldToScreen(entityPos);
      
      if (screenPos) {
        // 设置气泡位置（在实体头顶上方）
        bubble.element.style.left = `${screenPos.x}px`;
        bubble.element.style.top = `${screenPos.y - 80}px`; // 向上偏移80像素
        bubble.element.style.display = 'block';
      } else {
        // 如果实体不在屏幕内，隐藏气泡
        bubble.element.style.display = 'none';
      }
    } catch (error) {
      console.warn('更新气泡位置失败:', error);
      bubble.element.style.display = 'none';
    }
  }

  /**
   * 应用距离感知的缩放效果
   */
  private applyDistanceScaling(bubble: ChatBubble, entityPos: Vec3, playerPos: Vec3): void {
    const distance = this.calculateDistance(entityPos, playerPos);
    
    // 移除之前的距离类
    bubble.element.classList.remove('distant', 'very-distant');
    
    if (distance > this.maxDistance) {
      // 超出最大距离，隐藏气泡
      bubble.element.style.display = 'none';
      return;
    } else if (distance > this.maxDistance * 0.7) {
      // 很远的距离
      bubble.element.classList.add('very-distant');
    } else if (distance > this.maxDistance * 0.4) {
      // 中等距离
      bubble.element.classList.add('distant');
    }
    
    // 计算缩放比例
    const scale = Math.max(this.minScale, 1 - (distance / this.maxDistance) * 0.5);
    const currentTransform = bubble.element.style.transform;
    
    // 保持原有的translate，只修改scale
    if (currentTransform.includes('scale')) {
      bubble.element.style.transform = currentTransform.replace(/scale\([^)]*\)/, `scale(${scale})`);
    } else {
      bubble.element.style.transform = `${currentTransform} scale(${scale})`;
    }
  }

  /**
   * 计算两点间距离
   */
  private calculateDistance(pos1: Vec3, pos2: Vec3): number {
    const dx = pos1.x - pos2.x;
    const dy = pos1.y - pos2.y;
    const dz = pos1.z - pos2.z;
    return Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  /**
   * 世界坐标转屏幕坐标
   */
  private worldToScreen(worldPos: Vec3): { x: number; y: number } | null {
    if (!this.camera) return null;

    try {
      // 创建THREE.js向量
      const vector = new THREE.Vector3(worldPos.x, worldPos.y + 2.2, worldPos.z); // 向上偏移2.2格
      
      // 投影到屏幕坐标
      vector.project(this.camera);
      
      // 转换为屏幕像素坐标
      const x = (vector.x * 0.5 + 0.5) * window.innerWidth;
      const y = (vector.y * -0.5 + 0.5) * window.innerHeight;
      
      // 检查是否在屏幕范围内和相机前方
      if (x >= -100 && x <= window.innerWidth + 100 && 
          y >= -100 && y <= window.innerHeight + 100 && 
          vector.z < 1) {
        return { x, y };
      }
      
      return null;
    } catch (error) {
      console.warn('坐标转换失败:', error);
      return null;
    }
  }

  /**
   * 清理所有气泡
   */
  public clear(): void {
    for (const bubbleId of this.bubbles.keys()) {
      this.removeBubble(bubbleId);
    }
  }

  /**
   * 获取活跃气泡数量
   */
  public getActiveBubbleCount(): number {
    return Array.from(this.bubbles.values()).filter(bubble => bubble.isVisible).length;
  }

  /**
   * 检查实体是否有活跃气泡
   */
  public hasActiveBubble(entityId: string): boolean {
    const bubble = this.bubbles.get(entityId);
    return bubble ? bubble.isVisible : false;
  }

  /**
   * 设置最大显示距离
   */
  public setMaxDistance(distance: number): void {
    this.maxDistance = distance;
  }

  /**
   * 设置默认显示时长
   */
  public setDefaultDuration(duration: number): void {
    this.defaultDuration = duration;
  }

  /**
   * 获取调试信息
   */
  public getDebugInfo(): any {
    return {
      activeBubbles: this.getActiveBubbleCount(),
      totalBubbles: this.bubbles.size,
      maxDistance: this.maxDistance,
      defaultDuration: this.defaultDuration,
      bubbles: Array.from(this.bubbles.values()).map(bubble => ({
        entityId: bubble.id,
        entityType: bubble.entity.getType(),
        message: bubble.message.substring(0, 30) + (bubble.message.length > 30 ? '...' : ''),
        elapsed: Date.now() - bubble.startTime,
        duration: bubble.duration,
        isVisible: bubble.isVisible
      }))
    };
  }

  /**
   * 销毁管理器
   */
  public dispose(): void {
    this.clear();
    if (this.container && this.container.parentNode) {
      this.container.parentNode.removeChild(this.container);
    }
  }
}